package svc

import (
	"context"
	"sync"
	"time"

	"gitee.com/lyuanbo/stock-plus/internal/config"
	"gitee.com/lyuanbo/stock-plus/internal/models"
	"gitee.com/lyuanbo/stock-plus/pkg/consts"
	"gitee.com/lyuanbo/stock-plus/pkg/logger"
	"gitee.com/lyuanbo/stock-plus/pkg/stock"
	"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
	"github.com/go-redsync/redsync/v4"
	"github.com/nats-io/nats.go"
	"github.com/nats-io/nats.go/jetstream"
	"github.com/redis/go-redis/v9"
)

type ServiceContext struct {
	Ctx        context.Context
	Conf       *config.DynamicConf
	Redis      *redis.Client
	RedSync    *redsync.Redsync
	Nats       *nats.Conn
	JetStream  jetstream.JetStream
	Stream     jetstream.Stream
	ClickHouse driver.Conn

	Mux *sync.Mutex

	Stock  *stock.Stock
	Logger *logger.Logger

	Models Models
}

type Models struct {
	Realtime *models.RealtimeModel
	Kline    *models.KlineModel
}

type Options struct {
	Ctx        context.Context
	Conf       *config.DynamicConf
	Mux        *sync.Mutex
	Redis      *redis.Client
	RedSync    *redsync.Redsync
	Nats       *nats.Conn
	Stock      *stock.Stock
	ClickHouse driver.Conn
	Logger     *logger.Logger
	Models     Models
}

func NewServiceContext(options Options) *ServiceContext {
	svcCtx := &ServiceContext{
		Ctx:        options.Ctx,
		Mux:        options.Mux,
		Conf:       options.Conf,
		Redis:      options.Redis,
		RedSync:    options.RedSync,
		Nats:       options.Nats,
		Logger:     options.Logger,
		Stock:      options.Stock,
		ClickHouse: options.ClickHouse,
		Models:     options.Models,
	}

	svcCtx.JetStream, _ = jetstream.New(options.Nats)

	svcCtx.Stream, _ = svcCtx.JetStream.CreateStream(context.Background(), jetstream.StreamConfig{
		Name:     "default",
		Subjects: []string{consts.TopicRealTime},
		Storage:  jetstream.FileStorage,
		Replicas: 1,

		// 关键缺失配置
		Retention: jetstream.InterestPolicy, // 工作队列模式确保顺序
		MaxAge:    24 * time.Hour,           // 消息保留时间
		NoAck:     false,                    // 需要确认机制

		// 性能调优
		MaxMsgs:    10000,     // 限制消息总数
		MaxBytes:   100 << 20, // 100MB限制
		MaxMsgSize: 1 << 20,   // 1MB单消息限制

		// 去重优化
		Duplicates: 30 * time.Second, // 30秒
	})

	return svcCtx
}
